#!/usr/bin/env python
# -*- coding: utf8 -*-
"""
Enhance BlogoSerV CLI sender
"""

import re
import sys
import socket    # client side halfpair socket
import libxmlrpc

E_OK        = 0
E_ARGC      = 1
E_MALFORMED = 2

HOST='127.0.0.1'
PORT=5007

def f_err( errcode, errdesc=None ):
  if not errdesc is None:
    sys.stderr.write( '{E} %s\n' % ( errdesc ) )

  try:
    sock.shutdown( 2 )
    sock.close()
  except:
    pass

  sys.exit( errcode )

def _sendRequest_( data ):
  try:
    sended  = sock.send( 'POST / HTTP/1.0\nContent-Length: %d\nContent-Type: %s\n\n' % ( len( data ), 'text/xml' ) )
    sended += sock.send( '%s' % ( data ) )
  except:
    f_err( 25, 'Error while sending...' )

def _getResponce_( ):
  ContentLength = re.compile( 'Content-Length: ([0-9]+)' )

  data = sock.recv( 1024 )
  while data < 100:
    data += sock.recv( min( 100, 100-len(data) ) )

  # get ContentLength
  res = ContentLength.search( data )

  if res is None:
    f_err( E_MALFORMED, 'Content-Length header is missed' )

  ContentLength = int( res.groups( )[0] )

  del res

  # find doc start
  pos = data.find( '\n\n')
  if pos == -1:
    f_err( E_MALFORMED, 'Wrong responce received' )
  else:
    pos += 2

  # set data enter point
  data = data[pos:]
  while len( data ) < ContentLength:
    data += sock.recv( 1024 )

  return data

reSplitter    = re.compile( ' +' )

xmlrpc = libxmlrpc.XML_RPC( )

#if len( sys.argv ) < 2:
#  f_err( E_ARGC, 'Wrong ARGCount' )

#methodName = sys.argv[1]
#args = sys.argv[2:]


if len( sys.argv ) > 1:
	HOST = sys.argv[1]

if len( sys.argv ) > 2:
  try:
    PORT = int( sys.argv[2] )
  except:
    sys.stderr.write( 'Using default port instead of %s, causes wrong format\n' % ( sys.argv[2] ) )

sys.stdout.write( "Connecting to %s:%d..." % ( HOST, PORT ) )

sock = socket.socket( 2, 1 )
try:
  sock.connect( ( HOST, PORT ) )

except:
  sys.stdout.write( ' [ FAIL ]\n' )
  f_err( 5, 'Connect fault' )

else:
  sys.stdout.write( ' [  OK  ]\n' )

while 1:

  # USER INPUT
  try:
    args = sys.stdin.readline()[:-1]
  except:
    f_err( 1, 'Keyboard interrept failed' )

  if args in ( 'quit', 'exit' ):
    f_err( 0 )
  elif args == '':
    continue

  args = reSplitter.split( args )

  methodName = args[0]
  args = args[1:]

  xargs = [ xmlrpc.convPy2XML( arg ) for arg in args ]

  res = xmlrpc.methodCall( methodName, xargs )

  # DATA EXCHANGE
  _sendRequest_( res )
  res = _getResponce_()

  sys.stdout.flush()
 
  res = xmlrpc.parseResponce( res )
  
  ######### READY. START INTERPRETATION ###################
  
  if res[1] == 0:   # OK
    sys.stdout.write( '\033[32;8mOK\033[0m:\n' )
  
  elif res[1] == 1: # FAULT
    sys.stdout.write( '\033[33;8mFAIL\033[0m:\n' )
  
  else:             # ERROR
    sys.stdout.write( '\033[31;8mWRONG\033[0m:\n' )
  
  if res[0][1] is None:
    res[0][1] = 'utf-8'

  for xarg in res[2]:
    arg = xmlrpc.convXML2Py( xarg )
    if type( arg ) is dict:
      sys.stdout.write( '[*] struct:\n' )
      for key in arg.keys():
        print '\t%10s: %s' % ( key, arg[key] )

    elif type( arg ) is list: # got list
      print '[*] list: '
      for item in arg:
        print '\t%s' % ( item )
      print
  
    else:
      print '[*] %s' % ( arg )

f_err( E_OK )
